using System;
using System.Data;
using System.Xml;
using OR.Reuse.Persistence;



namespace OR.Lazarus.Library.DataTier.Compiled
{
	public class ObjectDetail : OR.Lazarus.Library.DataTier.Compiled.Lazarus.ObjectDetail
	{
        private string mPluralName;

        public string PluralName
        {
            get { return mPluralName; }
            set { mPluralName = value; }
        }

        public ObjectDetail Parent
		{
			get
			{
				return ( this.GetParent() );
			}
		}

		public TableDetail Table
		{
			get
			{
				return ( this.GetTable() );
			}
		}

		public virtual TableDetail GetTable()
		{
			return ( this.Project.Tables[ this.DBTable ] );
		}

		public ProjectDetail Project
		{
			get
			{
				return ( ProjectDetail )base.ParentEntity;
			}
			set
			{
				base.ParentEntity = value;
			}
		}

		protected virtual ObjectDetail GetParent()
		{
			ObjectDetail vReturn = null;

			if ( this.Implements.Count == 1 )
			{
				vReturn = this.Project.Objects[ this.Implements[ 0 ].Ref ];
			}

			return ( vReturn );
		}

		public virtual FieldDetail GetPKField()
		{
			FieldDetail v_oReturn = null;

			foreach ( FieldDetail v_oField in this.Fields )
			{
				if ( v_oField.IsPrimaryKey )
				{
					v_oReturn = v_oField;

					break;
				}
			}

			if ( ( v_oReturn == null ) && ( this.Parent != null ) )
			{
				v_oReturn = this.Parent.GetPKField();
			}

			return ( v_oReturn );
		}

		public bool IsRoot
		{
			get
			{
				return ( this.GetIsRoot() );
			}
		}

		protected virtual bool GetIsRoot()
		{
			return ( this.Implements.Count == 0 );
		}

		public virtual ObjectCollection GetInheritanceChain( ObjectCollection pContext )
		{
			ObjectCollection	vReturn	= new ObjectCollection();

			this.GetInheritanceChain( pContext, vReturn );

			return ( vReturn );
		}

		protected virtual void GetInheritanceChain( ObjectCollection pContext, ObjectCollection pResult )
		{
			ObjectDetail	vObject	= null;

			pResult.AddAt( 0, this );

			foreach ( ImplementDetail vImplement in this.Implements )
			{
				vObject = pContext[ vImplement.Ref ];

				vObject.Project = this.Project;

				if ( vObject == null )
				{
					throw new ApplicationException( String.Format( "Object [{0}] has an Implements reference to Object [{1}], which does not exist in the model.", this.Name,  vImplement.Ref ) );
				}

				vObject.GetInheritanceChain( pContext, pResult );
			}
		}

		public virtual FieldDetail GetClusteredField()
		{
			FieldDetail v_oReturn = null;

			foreach ( FieldDetail v_oField in this.Fields )
			{
				if ( v_oField.IsClustered )
				{
					v_oReturn = v_oField;

					break;
				}
			}

			return ( v_oReturn );
		}

		public override ObjectDetail CloneTyped()
		{
			ObjectDetail	vReturn = base.CloneTyped ();

			vReturn.Project = this.Project;

			return ( vReturn );
		}

        public override void LoadXml(XmlElement pSource)
        {
            base.LoadXml(pSource);

            mPluralName = DataUtility.GetString(pSource, "plural-name", String.Concat(this.Name, "s"));
        }

        public override XmlElement SaveXml(XmlDocument p_docContext)
        {
            XmlElement vReturn = base.SaveXml(p_docContext);

            vReturn.SetAttribute("plural-name", this.PluralName);

            return (vReturn);
        }
    }
}
